package com.huawei.demo;

import com.huaweicloud.sdk.cfw.v1.CfwClient;

import com.huaweicloud.sdk.cfw.v1.model.AddRuleAclDto;
import com.huaweicloud.sdk.cfw.v1.model.AddRuleAclDtoRules;
import com.huaweicloud.sdk.cfw.v1.model.AddRuleAclUsingPostRequest;
import com.huaweicloud.sdk.cfw.v1.model.AddRuleAclUsingPostResponse;
import com.huaweicloud.sdk.cfw.v1.model.DeleteRuleAclUsingDeleteRequest;
import com.huaweicloud.sdk.cfw.v1.model.DeleteRuleAclUsingDeleteResponse;
import com.huaweicloud.sdk.cfw.v1.model.EipResource;
import com.huaweicloud.sdk.cfw.v1.model.ListAccessControlLogsRequest;
import com.huaweicloud.sdk.cfw.v1.model.ListAccessControlLogsResponse;
import com.huaweicloud.sdk.cfw.v1.model.ListEipResourcesRequest;
import com.huaweicloud.sdk.cfw.v1.model.ListEipResourcesResponse;
import com.huaweicloud.sdk.cfw.v1.model.ListRuleAclUsingPutRequest;
import com.huaweicloud.sdk.cfw.v1.model.ListRuleAclsUsingGetRequest;
import com.huaweicloud.sdk.cfw.v1.model.ListRuleAclsUsingGetResponse;
import com.huaweicloud.sdk.cfw.v1.model.ListRuleHitCountDto;
import com.huaweicloud.sdk.cfw.v1.model.ListRuleHitCountRequest;
import com.huaweicloud.sdk.cfw.v1.model.ListRuleHitCountResponse;
import com.huaweicloud.sdk.cfw.v1.model.OrderRuleAclDto;
import com.huaweicloud.sdk.cfw.v1.model.RuleAddressDto;
import com.huaweicloud.sdk.cfw.v1.model.RuleServiceDto;
import com.huaweicloud.sdk.cfw.v1.model.UpdateRuleAclDto;
import com.huaweicloud.sdk.cfw.v1.model.UpdateRuleAclUsingPutRequest;
import com.huaweicloud.sdk.cfw.v1.model.UpdateRuleAclUsingPutResponse;
import com.huaweicloud.sdk.cfw.v1.region.CfwRegion;
import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.exception.ConnectionException;
import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
import com.huaweicloud.sdk.core.exception.ServiceResponseException;
import com.huaweicloud.sdk.core.utils.JsonUtils;

import java.util.ArrayList;
import java.util.List;

public class AclRule {
    public static void main(String[] args) {
        String ak = "<YOUR AK>";
        String sk = "<YOUR SK>";
        BasicCredentials auth = new BasicCredentials().withAk(ak).withSk(sk);
        CfwClient client = CfwClient.newBuilder().withCredential(auth).withRegion(CfwRegion.valueOf("<REGION ID>")).build();
        try {
            /* 4.4.1 通过查询防护eip列表查询到一条防护eip的地址 */
            String publicEIp = queryEip(client);

            /* 4.4.2 添加一条acl规则，方向为外到内、名称为ceshi、源地址为0.0.0.0/0、目的地址类型为ip地址、目的地址为防护eip、服务类型为服务、协议类型为TCP、源端口为0-65535、目的端口为0-65535、不支持长连接、动作为阻断、启用状态为打开 */
            String id = addAcl(client,publicEIp);

            /* 4.4.3 通过acl列表获取规则id */
            queryRuleId(client);

            /* 4.4.4 查询访问控制日志,获得阻断的访问控制日志 */
            queryAccessLog(client,publicEIp);

            /* 4.4.5 查询acl规则的击中次数 */
            queryRuleHitCount(client,id);

            /* 4.4.6 将acl规则置顶 */
            orderRule(client,id);

            /* 4.4.7 更新acl规则为一个非防护eip的值,其余不变 */
            updateAcl(client,id);

            /* 4.4.8 删除acl规则 */
            deleteAcl(client,id);
        } catch (ConnectionException e) {
            System.out.println(e.getMessage());
        } catch (RequestTimeoutException e) {
            System.out.println(e.getMessage());
        } catch (ServiceResponseException e) {
            System.out.println(e.getHttpStatusCode());
            System.out.println(e.getErrorCode());
            System.out.println(e.getErrorMsg());
        }
    }

    private static void orderRule(CfwClient client, String ruleId) {
        ListRuleAclUsingPutRequest listRuleAclUsingPutRequest = new ListRuleAclUsingPutRequest();
        OrderRuleAclDto orderRuleAclDto = new OrderRuleAclDto();
        orderRuleAclDto.setTop(1);
        listRuleAclUsingPutRequest.setAclRuleId(ruleId);
        listRuleAclUsingPutRequest.setBody(orderRuleAclDto);
        client.listRuleAclUsingPut(listRuleAclUsingPutRequest);
    }

    private static void queryRuleHitCount(CfwClient client, String ruleId) {
        ListRuleHitCountRequest listRuleHitCountRequest = new ListRuleHitCountRequest();
        ListRuleHitCountDto listRuleHitCountDto = new ListRuleHitCountDto();
        List<String> ruleIds = new ArrayList<>();
        ruleIds.add(ruleId);
        listRuleHitCountDto.setRuleIds(ruleIds);
        ListRuleHitCountResponse listRuleHitCountResponse = client.listRuleHitCount(listRuleHitCountRequest);
        System.out.println(listRuleHitCountResponse.toString());
    }

    private static void deleteAcl(CfwClient client, String id) {
        DeleteRuleAclUsingDeleteRequest deleteRuleAclUsingDeleteRequest = new DeleteRuleAclUsingDeleteRequest();
        deleteRuleAclUsingDeleteRequest.setAclRuleId(id);
        DeleteRuleAclUsingDeleteResponse deleteRuleAclUsingDeleteResponse = client.deleteRuleAclUsingDelete(deleteRuleAclUsingDeleteRequest);
        System.out.println(deleteRuleAclUsingDeleteResponse.toString());
    }

    private static void updateAcl(CfwClient client, String id) {
        UpdateRuleAclUsingPutRequest updateRuleAclUsingPutRequest = new UpdateRuleAclUsingPutRequest();
        updateRuleAclUsingPutRequest.setAclRuleId(id);
        UpdateRuleAclDto updateRuleAclDto = new UpdateRuleAclDto();
        updateRuleAclDto.setActionType(UpdateRuleAclDto.ActionTypeEnum.NUMBER_1);
        updateRuleAclDto.setAddressType(UpdateRuleAclDto.AddressTypeEnum.NUMBER_0);
        updateRuleAclDto.setDescription("");
        RuleAddressDto newDestination = new RuleAddressDto();
        newDestination.setAddress("1.1.1.1");
        newDestination.setType(0);
        updateRuleAclDto.setDestination(newDestination);
        updateRuleAclDto.setDirection(UpdateRuleAclDto.DirectionEnum.NUMBER_0);
        updateRuleAclDto.setLongConnectEnable(UpdateRuleAclDto.LongConnectEnableEnum.NUMBER_0);
        updateRuleAclDto.setName("ceshiAcl");
        RuleServiceDto ruleServiceDto = new RuleServiceDto();
        ruleServiceDto.setDestPort("0-65535");
        ruleServiceDto.setSourcePort("0-65535");
        ruleServiceDto.setProtocol(6);
        ruleServiceDto.setType(0);
        updateRuleAclDto.setService(ruleServiceDto);
        RuleAddressDto source = new RuleAddressDto();
        source.setAddress("0.0.0.0/0");
        source.setType(0);
        updateRuleAclDto.setSource(source);
        updateRuleAclDto.setStatus(1);
        updateRuleAclDto.setType(UpdateRuleAclDto.TypeEnum.NUMBER_0);
        updateRuleAclUsingPutRequest.setBody(updateRuleAclDto);
        System.out.println(JsonUtils.toJSON(updateRuleAclUsingPutRequest));
        UpdateRuleAclUsingPutResponse updateRuleAclUsingPutResponse = client.updateRuleAclUsingPut(updateRuleAclUsingPutRequest);
        System.out.println(updateRuleAclUsingPutResponse.toString());
    }

    private static void queryAccessLog(CfwClient client, String publicEIp) {
        ListAccessControlLogsRequest listAccessControlLogsRequest = new ListAccessControlLogsRequest();
        listAccessControlLogsRequest.setDstIp(publicEIp);
        listAccessControlLogsRequest.setFwInstanceId("<YOUR FirewallInstanceId>");
        listAccessControlLogsRequest.setStartTime(1670427589817L);
        listAccessControlLogsRequest.setEndTime(1670431189817L);
        listAccessControlLogsRequest.setLimit(10);
        ListAccessControlLogsResponse listAccessControlLogsResponse = client.listAccessControlLogs(listAccessControlLogsRequest);
        System.out.println(listAccessControlLogsResponse.toString());
    }

    private static String queryRuleId(CfwClient client) {
        ListRuleAclsUsingGetRequest listRuleAclsUsingGetRequest = new ListRuleAclsUsingGetRequest();
        listRuleAclsUsingGetRequest.setObjectId("<YOUR ObjectId>");
        listRuleAclsUsingGetRequest.setLimit(10);
        listRuleAclsUsingGetRequest.setOffset(0);
        ListRuleAclsUsingGetResponse listRuleAclsUsingGetResponse = client.listRuleAclsUsingGet(listRuleAclsUsingGetRequest);
        String ruleId = listRuleAclsUsingGetResponse.getData().getRecords().get(0).getRuleId();
        System.out.println(ruleId);
        return ruleId;
    }

    private static String addAcl(CfwClient client, String publicEIp) {
        AddRuleAclUsingPostRequest addRuleAclUsingPostRequest = new AddRuleAclUsingPostRequest();
        AddRuleAclDto addRuleAclDto = new AddRuleAclDto();
        addRuleAclDto.setObjectId("<YOUR ObjectId>");
        List<AddRuleAclDtoRules> addRuleAclDtoRulesList = new ArrayList<>();
        AddRuleAclDtoRules addRuleAclDtoRules = new AddRuleAclDtoRules();
        addRuleAclDtoRules.setActionType(1);
        addRuleAclDtoRules.setAddressType(AddRuleAclDtoRules.AddressTypeEnum.NUMBER_0);
        addRuleAclDtoRules.setDescription("");
        RuleAddressDto destination = new RuleAddressDto();
        destination.setAddress(publicEIp);
        destination.setType(0);
        addRuleAclDtoRules.setDestination(destination);
        addRuleAclDtoRules.setDirection(AddRuleAclDtoRules.DirectionEnum.NUMBER_0);
        addRuleAclDtoRules.setLongConnectEnable(AddRuleAclDtoRules.LongConnectEnableEnum.NUMBER_0);
        addRuleAclDtoRules.setName("ceshiAcl");
        OrderRuleAclDto orderRuleAclDto = new OrderRuleAclDto();
        orderRuleAclDto.setTop(1);
        addRuleAclDtoRules.setSequence(orderRuleAclDto);
        RuleServiceDto ruleServiceDto = new RuleServiceDto();
        ruleServiceDto.setDestPort("0-65535");
        ruleServiceDto.setSourcePort("0-65535");
        ruleServiceDto.setProtocol(6);
        ruleServiceDto.setType(0);
        addRuleAclDtoRules.setService(ruleServiceDto);
        RuleAddressDto source = new RuleAddressDto();
        source.setAddress("0.0.0.0/0");
        source.setType(0);
        addRuleAclDtoRules.setSource(source);
        addRuleAclDtoRules.setStatus(AddRuleAclDtoRules.StatusEnum.NUMBER_1);
        addRuleAclDtoRulesList.add(addRuleAclDtoRules);
        addRuleAclDto.setRules(addRuleAclDtoRulesList);
        addRuleAclDto.setType(AddRuleAclDto.TypeEnum.NUMBER_0);
        addRuleAclUsingPostRequest.setBody(addRuleAclDto);
        AddRuleAclUsingPostResponse addRuleAclUsingPostResponse = client.addRuleAclUsingPost(addRuleAclUsingPostRequest);
        String id = addRuleAclUsingPostResponse.getData().getRules().get(0).getId();
        System.out.println(id);
        return id;
    }

    private static String queryEip(CfwClient client) {
        ListEipResourcesRequest listEipResourcesRequest = new ListEipResourcesRequest();
        listEipResourcesRequest.setObjectId("<YOUR ObjectId>");
        listEipResourcesRequest.setLimit(10);
        listEipResourcesRequest.setOffset(0);
        listEipResourcesRequest.setSync(ListEipResourcesRequest.SyncEnum.NUMBER_1);
        ListEipResourcesResponse listEipResourcesResponse = client.listEipResources(listEipResourcesRequest);
        EipResource eipResource = listEipResourcesResponse.getData().getRecords().get(0);
        String publicEIp = eipResource.getPublicIp();
        System.out.println(publicEIp);
        return publicEIp;
    }
}
